/*
 *
 */
#include "Heroi.h"

#ifndef _HEROI_CPP_
#define _HEROI_CPP_

#define VELOCIDADE 0.1

using namespace std;

/*
 *seta o retângulo auxiliar de destino do Heroi
 */
void Heroi::setOrigAux(Sint16 _x,Sint16 _y,Uint16 _w,Uint16 _h)
{
   origAux->x = _x; //posição x do sprite na janela
   origAux->y = _y; //posição y do sprite na janela
   origAux->w = _w; //largura do sprite
   origAux->h = _h; //altura do sprite
}

tipoEstado Heroi::getEstado(void)
{
   return estado;
}

/*
 *método para verificar qual o estado atual do heroi e identificar o método correto a ser chamado para parar
 */
void Heroi::parar(void)
{
   switch(estado)
   {
      case parado:
         switch(posicao)
         {
            case direita:
               animacaoAtual = new Animacao(relogio,1,32,32,1,1);
               break;
            case esquerda:
               animacaoAtual = new Animacao(relogio,1,32,32,1,1);
               break;
            case cima:
               animacaoAtual = new Animacao(relogio,1,32,32,1,3);
               break;
            case baixo:
               animacaoAtual = new Animacao(relogio,1,32,32,1,3);
               break;
         }
         break;
     case andando:
         setVx(0);
         setVy(0);
         estado = parado;
         switch(posicao)
         {
            case direita:
               animacaoAtual = new Animacao(relogio,1,32,32,1,1);
               break;
            case esquerda:
               animacaoAtual = new Animacao(relogio,1,32,32,1,1);
               break;
            case cima:
               animacaoAtual = new Animacao(relogio,1,32,32,1,3);
               break;
            case baixo:
               animacaoAtual = new Animacao(relogio,1,32,32,1,3);
               break;
         }
         break;
     default:
         estado = parado;
         posicao = direita;
         setVx(0);
         setVy(0);
         animacaoAtual = new Animacao(relogio,1,32,32,1,1);
         break;
   }
}

/*
 *método que de acordo com o estado atual do heroi faz o processo correto para fazer o heroi andar para a direita
 */
void Heroi::andarDireita(void)
{
   switch(estado)
   {
      case andando:
         switch(posicao)
         {
            case direita:
               break;

            default:
               setQuadro(0);
               setVx(VELOCIDADE);
               setVy(0);
               posicao = direita;
               animacaoAtual  = new Animacao(relogio,2,32,32,30,1);
               break;
         }
         break;

      default:
         switch(posicao)
         {
            default:
               setQuadro(0);
               setVx(VELOCIDADE);
               setVy(0);
               estado = andando;
               posicao = direita;
               animacaoAtual  = new Animacao(relogio,2,32,32,30,1);
               break;
         }
         break;
   }
}

/*
 *método que de acordo com o estado atual do heroi, identifica qual o processo correto para fazer o heroi andar para a esquerda
 */
void Heroi::andarEsquerda(void)
{
   switch(estado)
   {
      case andando:
         switch(posicao)
         {
            case esquerda:
               break;

            default:
               setQuadro(0);
               setVx(-VELOCIDADE);
               setVy(0);
               posicao = esquerda;
               animacaoAtual = new Animacao(relogio,2,32,32,30,4);
               break;
         }
         break;

      default:
         switch(posicao)
         {
            default:
               setQuadro(0);
               setVx(-VELOCIDADE);
               setVy(0);
               estado = andando;
               posicao = esquerda;
               animacaoAtual = new Animacao(relogio,2,32,32,30,4);
               break;
         }
         break;
   }
}

/*
 *
 */
void Heroi::andarCima(void)
{
   switch(estado)
   {
      case andando:
         switch(posicao)
         {
            case cima:
               break;

            default:
               setQuadro(0);
               setVx(0);
               setVy(-VELOCIDADE);
               posicao = cima;
               animacaoAtual = new Animacao(relogio,2,32,32,30,3);
               break;
         }
         break;

      default:
         switch(posicao)
         {
            default:
               setQuadro(0);
               setVx(0);
               setVy(-VELOCIDADE);
               estado = andando;
               posicao = cima;
               animacaoAtual = new Animacao(relogio,2,32,32,30,3);
               break;
         }
         break;
   }
}

/*
 *
 */
void Heroi::andarBaixo(void)
{
   switch(estado)
   {
      case andando:
         switch(posicao)
         {
            case baixo:
               break;

            default:
               setQuadro(0);
               setVx(0);
               setVy(VELOCIDADE);
               posicao = baixo;
               animacaoAtual = new Animacao(relogio,2,32,32,30,2);
               break;
         }
         break;

      default:
         switch(posicao)
         {
            default:
               setQuadro(0);
               setVx(0);
               setVy(VELOCIDADE);
               estado = andando;
               posicao = baixo;
               animacaoAtual = new Animacao(relogio,2,32,32,30,2);
               break;
         }
         break;
   }
}

/*
 *Processo que chama o método de movimento correto do Sprite em relação as teclas pressionadas
 */
void Heroi::processaTeclas(MapaTeclas *tecla,Audio *audio)
{
   bool parado = true;   //Se existe alguma tecla pressionada o valor dela é false
   //caso as teclas direcionais opostas estiverem sendo pressionadas ao mesmo tempo...
   if((tecla->getDireita() && tecla->getEsquerda()) || (tecla->getCima() && tecla->getBaixo()))
   {
      ;//nada faz, ou seja, continua parado
   }
   else
   {
      if(tecla->getDireita())
      {
         andarDireita();
         parado = false;
      }
      else if(tecla->getEsquerda())
      {
         andarEsquerda();
         parado = false;
      }
      else if(tecla->getCima())
      {
         andarCima();
         parado = false;
      }
      else if(tecla->getBaixo())
      {
         andarBaixo();
         parado = false;
      }
   }

   if(parado)
   {
      passos->parar(0);
      parar();
   }
   else
   {
      passos->tocar();
   }
}

/*
 *Método para ser executado no final do periodo de um ciclo de um loop para mostrar desenharo heroi na cena
 */
void Heroi::blitHeroi()
{
      Uint32 deltaTempo;
      deltaTempo = animacaoAtual->animar(origAux);
      limparSprite();   //limpa o Sprite da janela
      setarSprite(origAux->x,origAux->y,origAux->w,origAux->h); //atualiza os retângulos de origem e destino do Heroi
      blitSprite();     //desenha o Heroi na cena
}

Heroi::Heroi(string nomeArquivo,Video *video, Audio *audio, Relogio *relogio,Sint16 orig_x, Sint16 orig_y, Uint16 orig_w, Uint16 orig_h, float dest_x, float dest_y, Uint16 dest_w, Uint16 dest_h)
{

   setVideo(video);
   setRelogio(relogio);

   setOrig(orig_x, orig_y, orig_w, orig_h);
   setDest(dest_x, dest_y, dest_w, dest_h);

   /*carrega as imagens*/
   carregarImagem(nomeArquivo);

   /*inicializa a animaçãos*/
   animacaoAtual = new Animacao(relogio,1,32,32,1,1);

   /*inicializa os efeitos sonoros*/
   passos = new EfeitoSonoro("efeitos_sonoros/step1.wav", 80, -1, 0, audio);

   origAux = new SDL_Rect;

   setOrigAux(orig_x, orig_y, orig_w, orig_h);
   estado = parado;
   posicao = direita;
}

Heroi::~Heroi()
{
   delete(origAux);
   delete(animacaoAtual);
   delete(passos);
}

#endif

